﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.ServiceProcess;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace ShutDownX
{
    public partial class Form1 : QT.Windows.Shell.GlassForm
    {
        string ServiceName = "ShutDownX";

        private Thread myThread = null;
        private delegate void myDeleGateshowTime(string s);
        private delegate DateTime myDeleGategetTime();
        private delegate List<string> myDeleGategetProcess();

        public Form1()
        {
            InitializeComponent();
            loadForm();
        }

        private void gbtnSave_Click(object sender, EventArgs e)
        {
            if (!this.cbService.Checked)
            {
                MessageBox.Show("本程序还没有安装为服务");
                return;
            }
            if (this.rtbProcess.Text.Length == 0)
            {
                if (MessageBox.Show("您还没有设置需要关闭的进程，确认不设置吗？", "系统提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) return;
            }

            Configuration appConfig = null;
            try
            {
                appConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                appConfig.AppSettings.Settings["Time"].Value = this.dtpTime.Value.ToString("HH:mm:ss");
                appConfig.AppSettings.Settings["Processes"].Value = this.rtbProcess.Text;
                appConfig.Save();
                MessageBox.Show("保存成功");
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {

                if (appConfig != null) appConfig = null;
            }
        }

        private void gbtnStart_Click(object sender, EventArgs e)
        {
            if (myThread != null && myThread.IsAlive) return;
            myThread = new Thread(new ThreadStart(ThreadShutDown));
            myThread.Start();
        }

        private void ThreadShutDown()
        {
            TimeSpan diffTime = new TimeSpan();
            DateTime myTime = getTime();

            while (true)
            {
                diffTime = myTime.Subtract(DateTime.Now);
                if (diffTime.TotalMilliseconds < 1)
                {
                    ShutDown();
                    return;
                }
                showTime(string.Format("距离关机还有：{0}时{1}分{2}秒", diffTime.Hours, diffTime.Minutes, diffTime.Seconds));

                Thread.Sleep(1000);
            }
        }

        private void ShutDown()
        {
            Process[] processes = Process.GetProcesses();
            List<string> myProcesses = getProcess();
            foreach (Process p in processes)
            {
                try
                {
                    if (myProcesses.Contains(p.MainModule.ModuleName.ToLower()))
                    {
                        if (!p.CloseMainWindow()) MessageBox.Show("进程关闭失败：" + p.MainModule.ModuleName);
                    }
                }
                catch
                {
                    continue;
                }
            }
            Process.Start("shutdown.exe", "-f -s -t 240");
        }

        private void showTime(string s)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new myDeleGateshowTime(showTime), new object[] { s });
            }
            else
            {
                this.Text = s;
            }
        }

        private DateTime getTime()
        {
            if (this.InvokeRequired)
            {
                return (DateTime)this.Invoke(new myDeleGategetTime(getTime));
            }
            else
            {
                return this.dtpTime.Value;
            }
        }

        private List<string> getProcess()
        {
            if (this.InvokeRequired)
            {
                return this.Invoke(new myDeleGategetProcess(getProcess)) as List<string>;
            }
            else
            {
                return new List<string>(this.rtbProcess.Text.ToLower().Split('|'));
            }
        }

        private void cbService_Click(object sender, EventArgs e)
        {
            if (this.cbService.Checked)
            {
                CreateService();
            }
            else
            {
                DeleteService();
            }
        }

        #region Method

        private void loadForm()
        {
            try
            {
                if (CheckService()) this.cbService.Checked = true;
                else this.cbService.Checked = false;

                DateTime Time = DateTime.Parse(ConfigurationManager.AppSettings["Time"]);
                string Processes = ConfigurationManager.AppSettings["Processes"];

                this.dtpTime.Value = Time;
                this.rtbProcess.Text = Processes;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private bool CheckService()
        {
            ServiceController[] sc = ServiceController.GetServices();

            foreach (ServiceController service in sc)
            {
                if (service.ServiceName.ToUpper() == ServiceName.ToUpper()) return true;
                service.Dispose();
            }

            sc = null;

            return false;
        }

        private bool CreateService()
        {
            if (CheckService())
            {
                MessageBox.Show("服务已存在");
                return false;
            }

            Process process = new Process();
            try
            {
                process.StartInfo.RedirectStandardInput = true;
                process.StartInfo.RedirectStandardOutput = true;
                process.StartInfo.CreateNoWindow = true;
                process.StartInfo.FileName = "sc.exe";
                process.StartInfo.Arguments = " create " + ServiceName + " binPath= \"" + Application.ExecutablePath + " -service\" type= \"share\" type= \"interact\" obj= \"LocalSystem\" start= \"auto\"";
                process.StartInfo.UseShellExecute = false;
                process.Start();
                string Result = process.StandardOutput.ReadToEnd();
                process.WaitForExit();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                process.Close();
            }

            if (!CheckService())
            {
                MessageBox.Show("安装失败");
                return false;
            }

            ServiceController sc = new ServiceController(ServiceName);
            try
            {
                sc.Start();
                sc.WaitForStatus(ServiceControllerStatus.Running);
                MessageBox.Show("安装完成。服务状态:" + sc.Status.ToString());
            }
            catch (InvalidOperationException ex)
            {
                MessageBox.Show(ex.Message);
                return false;
            }
            catch (Exception)
            {
                MessageBox.Show("系统错误");
                return false;
            }
            finally
            {
                sc.Dispose();
            }

            return true;
        }

        private bool DeleteService()
        {
            if (!CheckService())
            {
                MessageBox.Show("服务不存在");
                return false;
            }

            ServiceController sc = new ServiceController(ServiceName);
            try
            {
                if (sc.Status != ServiceControllerStatus.Stopped) sc.Stop();
            }
            catch (InvalidOperationException ex)
            {
                MessageBox.Show(ex.Message);
                return false;
            }
            catch (Exception)
            {
                MessageBox.Show("系统错误");
                return false;
            }
            finally
            {
                sc.Dispose();
            }

            Process process = new Process();
            try
            {
                process.StartInfo.RedirectStandardInput = true;
                process.StartInfo.RedirectStandardOutput = true;
                process.StartInfo.CreateNoWindow = true;
                process.StartInfo.FileName = "sc.exe";
                process.StartInfo.Arguments = " delete " + ServiceName;
                process.StartInfo.UseShellExecute = false;
                process.Start();
                string Result = process.StandardOutput.ReadToEnd();
                process.WaitForExit();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                process.Close();
            }

            if (CheckService())
            {
                MessageBox.Show("卸载失败");
                return false;
            }
            else
            {
                MessageBox.Show("卸载完成");
                return true;
            }
        }

        #endregion
    }
}
